import 'dart:math';
import 'dart:io';
import '../models/hexagram.dart';

class HexagramService {
  static final HexagramService _instance = HexagramService._internal();
  factory HexagramService() => _instance;
  HexagramService._internal();
  
  // 八卦基本数据
  final Map<String, Map<String, dynamic>> _basicHexagrams = {
    '乾': {'symbol': '☰', 'nature': '天', 'element': '金'},
    '坤': {'symbol': '☷', 'nature': '地', 'element': '土'},
    '震': {'symbol': '☳', 'nature': '雷', 'element': '木'},
    '巽': {'symbol': '☴', 'nature': '风', 'element': '木'},
    '坎': {'symbol': '☵', 'nature': '水', 'element': '水'},
    '离': {'symbol': '☲', 'nature': '火', 'element': '火'},
    '艮': {'symbol': '☶', 'nature': '山', 'element': '土'},
    '兑': {'symbol': '☱', 'nature': '泽', 'element': '金'},
  };
  
  // 六十四卦数据（简化版，实际应用中应包含完整数据）
  final List<Map<String, dynamic>> _hexagramData = [
    {'name': '乾为天', 'upper': '乾', 'lower': '乾', 'description': '天行健，君子以自强不息'},
    {'name': '坤为地', 'upper': '坤', 'lower': '坤', 'description': '地势坤，君子以厚德载物'},
    {'name': '水雷屯', 'upper': '坎', 'lower': '震', 'description': '云雷屯，君子以经纶'},
    {'name': '山水蒙', 'upper': '艮', 'lower': '坎', 'description': '山下出泉，蒙；君子以果行育德'},
    {'name': '水天需', 'upper': '坎', 'lower': '乾', 'description': '云上于天，需；君子以饮食宴乐'},
    {'name': '天水讼', 'upper': '乾', 'lower': '坎', 'description': '天与水违行，讼；君子以作事谋始'},
    {'name': '地水师', 'upper': '坤', 'lower': '坎', 'description': '地中有水，师；君子以容民畜众'},
    {'name': '水地比', 'upper': '坎', 'lower': '坤', 'description': '地上有水，比；先王以建万国，亲诸侯'},
    {'name': '风天小畜', 'upper': '巽', 'lower': '乾', 'description': '风行天上，小畜；君子以懿文德'},
    {'name': '天泽履', 'upper': '乾', 'lower': '兑', 'description': '上天下泽，履；君子以辨上下，定民志'},
    {'name': '地天泰', 'upper': '坤', 'lower': '乾', 'description': '天地交，泰；后以财成天地之道，辅相天地之宜，以左右民'},
    {'name': '天地否', 'upper': '乾', 'lower': '坤', 'description': '天地不交，否；君子以俭德辟难，不可荣以禄'},
    {'name': '天火同人', 'upper': '乾', 'lower': '离', 'description': '天与火，同人；君子以类族辨物'},
    {'name': '火天大有', 'upper': '离', 'lower': '乾', 'description': '火在天上，大有；君子以遏恶扬善，顺天休命'},
    {'name': '地山谦', 'upper': '坤', 'lower': '艮', 'description': '地中有山，谦；君子以裒多益寡，称物平施'},
    {'name': '雷地豫', 'upper': '震', 'lower': '坤', 'description': '雷出地奋，豫；先王以作乐崇德，殷荐之上帝，以配祖考'},
    {'name': '泽雷随', 'upper': '兑', 'lower': '震', 'description': '泽中有雷，随；君子以向晦入宴息'},
    {'name': '山风蛊', 'upper': '艮', 'lower': '巽', 'description': '山下有风，蛊；君子以振民育德'},
    {'name': '地泽临', 'upper': '坤', 'lower': '兑', 'description': '泽上有地，临；君子以教思无穷，容保民无疆'},
    {'name': '风地观', 'upper': '巽', 'lower': '坤', 'description': '风行地上，观；先王以省方观民设教'},
    {'name': '火雷噬嗑', 'upper': '离', 'lower': '震', 'description': '雷电噬嗑；先王以明罚敕法'},
    {'name': '山火贲', 'upper': '艮', 'lower': '离', 'description': '山下有火，贲；君子以明庶政，无敢折狱'},
    {'name': '山地剥', 'upper': '艮', 'lower': '坤', 'description': '山附于地，剥；上以厚下，安宅'},
    {'name': '地雷复', 'upper': '坤', 'lower': '震', 'description': '雷在地中，复；先王以至日闭关，商旅不行，后不省方'},
    {'name': '天雷无妄', 'upper': '乾', 'lower': '震', 'description': '天下雷行，物与无妄；先王以茂对时育万物'},
    {'name': '山天大畜', 'upper': '艮', 'lower': '乾', 'description': '天在山中，大畜；君子以多识前言往行，以畜其德'},
    {'name': '山雷颐', 'upper': '艮', 'lower': '震', 'description': '山下有雷，颐；君子以慎言语，节饮食'},
    {'name': '泽风大过', 'upper': '兑', 'lower': '巽', 'description': '泽灭木，大过；君子以独立不惧，遁世无闷'},
    {'name': '坎为水', 'upper': '坎', 'lower': '坎', 'description': '水洊至，习坎；君子以常德行，习教事'},
    {'name': '离为火', 'upper': '离', 'lower': '离', 'description': '明两作，离；大人以继明照于四方'},
    {'name': '泽山咸', 'upper': '兑', 'lower': '艮', 'description': '山上有泽，咸；君子以虚受人'},
    {'name': '雷风恒', 'upper': '震', 'lower': '巽', 'description': '雷风，恒；君子以立不易方'},
    {'name': '天山遁', 'upper': '乾', 'lower': '艮', 'description': '天下有山，遁；君子以远小人，不恶而严'},
    {'name': '雷天大壮', 'upper': '震', 'lower': '乾', 'description': '雷在天上，大壮；君子以非礼弗履'},
    {'name': '火地晋', 'upper': '离', 'lower': '坤', 'description': '明出地上，晋；君子以自昭明德'},
    {'name': '地火明夷', 'upper': '坤', 'lower': '离', 'description': '明入地中，明夷；君子以莅众，用晦而明'},
    {'name': '风火家人', 'upper': '巽', 'lower': '离', 'description': '风自火出，家人；君子以言有物，而行有恒'},
    {'name': '火泽睽', 'upper': '离', 'lower': '兑', 'description': '上火下泽，睽；君子以同而异'},
    {'name': '水山蹇', 'upper': '坎', 'lower': '艮', 'description': '山上有水，蹇；君子以反身修德'},
    {'name': '雷水解', 'upper': '震', 'lower': '坎', 'description': '雷雨作，解；君子以赦过宥罪'},
    {'name': '山泽损', 'upper': '艮', 'lower': '兑', 'description': '山下有泽，损；君子以惩忿窒欲'},
    {'name': '风雷益', 'upper': '巽', 'lower': '震', 'description': '风雷，益；君子以见善则迁，有过则改'},
    {'name': '泽天夬', 'upper': '兑', 'lower': '乾', 'description': '泽上于天，夬；君子以施禄及下，居德则忌'},
    {'name': '天风姤', 'upper': '乾', 'lower': '巽', 'description': '天下有风，姤；后以施命诰四方'},
    {'name': '泽地萃', 'upper': '兑', 'lower': '坤', 'description': '泽上于地，萃；君子以除戎器，戒不虞'},
    {'name': '地风升', 'upper': '坤', 'lower': '巽', 'description': '地中生木，升；君子以顺德，积小以高大'},
    {'name': '泽水困', 'upper': '兑', 'lower': '坎', 'description': '泽无水，困；君子以致命遂志'},
    {'name': '水风井', 'upper': '坎', 'lower': '巽', 'description': '木上有水，井；君子以劳民劝相'},
    {'name': '泽火革', 'upper': '兑', 'lower': '离', 'description': '泽中有火，革；君子以治历明时'},
    {'name': '火风鼎', 'upper': '离', 'lower': '巽', 'description': '木上有火，鼎；君子以正位凝命'},
    {'name': '震为雷', 'upper': '震', 'lower': '震', 'description': '洊雷，震；君子以恐惧修省'},
    {'name': '艮为山', 'upper': '艮', 'lower': '艮', 'description': '兼山，艮；君子以思不出其位'},
    {'name': '风山渐', 'upper': '巽', 'lower': '艮', 'description': '山上有木，渐；君子以居贤德善俗'},
    {'name': '雷泽归妹', 'upper': '震', 'lower': '兑', 'description': '泽上有雷，归妹；君子以永终知敝'},
    {'name': '雷火丰', 'upper': '震', 'lower': '离', 'description': '雷电皆至，丰；君子以折狱致刑'},
    {'name': '火山旅', 'upper': '离', 'lower': '艮', 'description': '山上有火，旅；君子以明慎用刑，而不留狱'},
    {'name': '巽为风', 'upper': '巽', 'lower': '巽', 'description': '随风，巽；君子以申命行事'},
    {'name': '兑为泽', 'upper': '兑', 'lower': '兑', 'description': '丽泽，兑；君子以朋友讲习'},
    {'name': '风水涣', 'upper': '巽', 'lower': '坎', 'description': '风行水上，涣；先王以享于帝，立庙'},
    {'name': '水泽节', 'upper': '坎', 'lower': '兑', 'description': '泽上有水，节；君子以制数度，议德行'},
    {'name': '风泽中孚', 'upper': '巽', 'lower': '兑', 'description': '泽上有风，中孚；君子以议狱缓死'},
    {'name': '雷山小过', 'upper': '震', 'lower': '艮', 'description': '山上有雷，小过；君子以行过乎恭，丧过乎哀，用过乎俭'},
    {'name': '水火既济', 'upper': '坎', 'lower': '离', 'description': '水在火上，既济；君子以思患而豫防之'},
    {'name': '火水未济', 'upper': '离', 'lower': '坎', 'description': '火在水上，未济；君子以慎辨物居方'},
  ];
  
  // 根据时间生成卦象
  Hexagram generateFromTime(DateTime time) {
    // 使用时间的小时、分钟、秒数作为种子
    int seed = time.hour * 3600 + time.minute * 60 + time.second;
    Random random = Random(seed);
    
    // 随机选择一个卦象
    int index = random.nextInt(_hexagramData.length);
    Map<String, dynamic> hexagramInfo = _hexagramData[index];
    
    String upperHexagram = hexagramInfo['upper'];
    String lowerHexagram = hexagramInfo['lower'];
    
    return Hexagram(
      name: hexagramInfo['name'],
      upperSymbol: _basicHexagrams[upperHexagram]?['symbol'] ?? '',
      lowerSymbol: _basicHexagrams[lowerHexagram]?['symbol'] ?? '',
      description: hexagramInfo['description'],
      upperElement: _basicHexagrams[upperHexagram]?['element'] ?? '',
      lowerElement: _basicHexagrams[lowerHexagram]?['element'] ?? '',
    );
  }
  
  // 根据数字生成卦象
  Hexagram generateFromNumbers(int number1, int number2) {
    // 确保数字在有效范围内
    number1 = (number1 - 1) % 8 + 1;
    number2 = (number2 - 1) % 8 + 1;
    
    // 映射到八卦
    List<String> bagua = _basicHexagrams.keys.toList();
    String upperHexagram = bagua[number1 - 1];
    String lowerHexagram = bagua[number2 - 1];
    
    // 查找对应的六十四卦
    Map<String, dynamic>? hexagramInfo;
    for (var hexagram in _hexagramData) {
      if (hexagram['upper'] == upperHexagram && hexagram['lower'] == lowerHexagram) {
        hexagramInfo = hexagram;
        break;
      }
    }
    
    // 如果没有找到匹配的卦象，使用默认值
    hexagramInfo ??= _hexagramData[0];
    
    return Hexagram(
      name: hexagramInfo['name'],
      upperSymbol: _basicHexagrams[upperHexagram]?['symbol'] ?? '',
      lowerSymbol: _basicHexagrams[lowerHexagram]?['symbol'] ?? '',
      description: hexagramInfo['description'],
      upperElement: _basicHexagrams[upperHexagram]?['element'] ?? '',
      lowerElement: _basicHexagrams[lowerHexagram]?['element'] ?? '',
    );
  }
  
  // 根据文本关键词生成卦象
  Future<Hexagram> generateFromText(String text) async {
    // 实际应用中，这里可以调用NLP API提取关键词
    // 然后根据关键词映射到卦象
    // 这里使用简化的随机方法
    Random random = Random(text.hashCode);
    int index = random.nextInt(_hexagramData.length);
    Map<String, dynamic> hexagramInfo = _hexagramData[index];
    
    String upperHexagram = hexagramInfo['upper'];
    String lowerHexagram = hexagramInfo['lower'];
    
    return Hexagram(
      name: hexagramInfo['name'],
      upperSymbol: _basicHexagrams[upperHexagram]?['symbol'] ?? '',
      lowerSymbol: _basicHexagrams[lowerHexagram]?['symbol'] ?? '',
      description: hexagramInfo['description'],
      upperElement: _basicHexagrams[upperHexagram]?['element'] ?? '',
      lowerElement: _basicHexagrams[lowerHexagram]?['element'] ?? '',
    );
  }
  
  // 根据图像生成卦象
  Future<Hexagram> generateFromImage(String imagePath) async {
    // 实际应用中，这里可以调用图像识别API提取特征
    // 然后根据特征映射到卦象
    // 这里使用简化的分析方法
    try {
      // 获取文件信息
      File imageFile = File(imagePath);
      bool fileExists = await imageFile.exists();
      
      if (!fileExists) {
        // 文件不存在，使用随机方法
        return _generateRandomHexagram(imagePath);
      }
      
      // 获取文件统计信息
      FileStat stat = await imageFile.stat();
      int fileSize = stat.size;
      DateTime lastModified = stat.modified;
      
      // 分析文件名中的关键词
      String fileName = imageFile.uri.pathSegments.last;
      String fileNameWithoutExtension = fileName.split('.').first;
      
      // 根据文件大小和修改时间生成种子
      int sizeSeed = (fileSize ~/ 1024) % 1000; // 以KB为单位
      int timeSeed = lastModified.millisecondsSinceEpoch ~/ 1000; // 以秒为单位
      int nameSeed = fileNameWithoutExtension.hashCode;
      
      // 综合种子
      int combinedSeed = (sizeSeed * 31 + timeSeed * 17 + nameSeed * 7) % 2147483647;
      Random random = Random(combinedSeed);
      
      // 根据文件名关键词调整卦象选择
      int index = random.nextInt(_hexagramData.length);
      
      // 根据文件名中的关键词调整卦象
      if (fileNameWithoutExtension.contains('山') || fileNameWithoutExtension.contains('mountain')) {
        // 增加艮卦（山）的概率
        if (random.nextDouble() < 0.3) {
          index = _findHexagramIndex('艮', random);
        }
      } else if (fileNameWithoutExtension.contains('水') || fileNameWithoutExtension.contains('water')) {
        // 增加坎卦（水）的概率
        if (random.nextDouble() < 0.3) {
          index = _findHexagramIndex('坎', random);
        }
      } else if (fileNameWithoutExtension.contains('火') || fileNameWithoutExtension.contains('fire')) {
        // 增加离卦（火）的概率
        if (random.nextDouble() < 0.3) {
          index = _findHexagramIndex('离', random);
        }
      } else if (fileNameWithoutExtension.contains('风') || fileNameWithoutExtension.contains('wind')) {
        // 增加巽卦（风）的概率
        if (random.nextDouble() < 0.3) {
          index = _findHexagramIndex('巽', random);
        }
      }
      
      Map<String, dynamic> hexagramInfo = _hexagramData[index];
      
      String upperHexagram = hexagramInfo['upper'];
      String lowerHexagram = hexagramInfo['lower'];
      
      return Hexagram(
        name: hexagramInfo['name'],
        upperSymbol: _basicHexagrams[upperHexagram]?['symbol'] ?? '',
        lowerSymbol: _basicHexagrams[lowerHexagram]?['symbol'] ?? '',
        description: hexagramInfo['description'],
        upperElement: _basicHexagrams[upperHexagram]?['element'] ?? '',
        lowerElement: _basicHexagrams[lowerHexagram]?['element'] ?? '',
      );
    } catch (e) {
      // 出现异常时使用随机方法
      return _generateRandomHexagram(imagePath);
    }
  }
  
  // 生成随机卦象的辅助方法
  Hexagram _generateRandomHexagram(String seedString) {
    Random random = Random(seedString.hashCode);
    int index = random.nextInt(_hexagramData.length);
    Map<String, dynamic> hexagramInfo = _hexagramData[index];
    
    String upperHexagram = hexagramInfo['upper'];
    String lowerHexagram = hexagramInfo['lower'];
    
    return Hexagram(
      name: hexagramInfo['name'],
      upperSymbol: _basicHexagrams[upperHexagram]?['symbol'] ?? '',
      lowerSymbol: _basicHexagrams[lowerHexagram]?['symbol'] ?? '',
      description: hexagramInfo['description'],
      upperElement: _basicHexagrams[upperHexagram]?['element'] ?? '',
      lowerElement: _basicHexagrams[lowerHexagram]?['element'] ?? '',
    );
  }
  
  // 查找特定卦象的索引
  int _findHexagramIndex(String baguaName, Random random) {
    List<int> indices = [];
    for (int i = 0; i < _hexagramData.length; i++) {
      if (_hexagramData[i]['upper'] == baguaName || _hexagramData[i]['lower'] == baguaName) {
        indices.add(i);
      }
    }
    
    if (indices.isNotEmpty) {
      return indices[random.nextInt(indices.length)];
    }
    
    return random.nextInt(_hexagramData.length);
  }
  
  // 获取所有卦象
  List<Hexagram> getAllHexagrams() {
    List<Hexagram> result = [];
    
    for (var hexagramInfo in _hexagramData) {
      String upperHexagram = hexagramInfo['upper'];
      String lowerHexagram = hexagramInfo['lower'];
      
      result.add(Hexagram(
        name: hexagramInfo['name'],
        upperSymbol: _basicHexagrams[upperHexagram]?['symbol'] ?? '',
        lowerSymbol: _basicHexagrams[lowerHexagram]?['symbol'] ?? '',
        description: hexagramInfo['description'],
        upperElement: _basicHexagrams[upperHexagram]?['element'] ?? '',
        lowerElement: _basicHexagrams[lowerHexagram]?['element'] ?? '',
      ));
    }
    
    return result;
  }
}